package com.yanqu.road.web.controller.usercenter.newadmin;


import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.dao.impl.admin.AdminCommonDaoImpl;
import com.yanqu.road.dao.impl.servercenter.CrossServerInfoDaoImpl;
import com.yanqu.road.entity.admin.AdminResult;
import com.yanqu.road.entity.cricket.config.CricketCourtConfig;
import com.yanqu.road.entity.servercenter.CrossServerInfo;
import com.yanqu.road.entity.servercenter.ProcessInfo;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.web.ICrossWebService;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.CrossServerType;
import com.yanqu.road.utils.config.Config;
import com.yanqu.road.utils.http.HttpHelper;
import com.yanqu.road.utils.string.StringUtils;
import com.yanqu.road.web.WebServer;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 63.促织竞技场配置
 */
@RestController
@RequestMapping("/usercenter/admin")
public class CenterCricketConfigController {

    /**
     *  63.1 修改
     */
    @ResponseBody
    @RequestMapping(value = "updateCricketConfig", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public String updateCricketConfig(HttpServletRequest request, @RequestBody JSONObject jsonObject) {


        CricketCourtConfig courtConfig = new CricketCourtConfig();
        int channelId = jsonObject.getIntValue("channelId");
        courtConfig.setChannelId(channelId);
        courtConfig.setCourtType(jsonObject.getIntValue("courtType"));
        courtConfig.setCourtName(jsonObject.getString("courtName"));
        courtConfig.setFightRangeServer(jsonObject.getIntValue("serverRange"));
        courtConfig.setFightRangeDay(jsonObject.getString("openServerDays"));
        courtConfig.setNum(jsonObject.getIntValue("membersNum"));
        courtConfig.setGroupLimit(jsonObject.getIntValue("groupsLimit"));
        courtConfig.setUpNum(jsonObject.getIntValue("roundRisePermillage"));
        courtConfig.setKeepNum(jsonObject.getIntValue("roundReservePermillage"));
        courtConfig.setModLimit(jsonObject.getIntValue("groupRemainderUpperLimit"));
        courtConfig.setReward(jsonObject.getString("endReward"));
        courtConfig.setRankReward(jsonObject.getString("rankReward"));
        courtConfig.setCourtState(jsonObject.getIntValue("courtSwitch"));


        boolean b = new AdminCommonDaoImpl().updateCricketConfig(courtConfig);

        if(b){
            return AdminResult.defaultInstance().toJsonString();
        }

        return AdminResult.failMsg("更新失败").toJsonString();
    }

    /**
     *  63.2 刷新
     */
    @ResponseBody
    @RequestMapping(value = "reloadCricketConfig", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public String reloadCricketConfig(HttpServletRequest request, @RequestBody JSONObject jsonObject) {
        int channelId = jsonObject.getIntValue("channelId");

        List<ProcessInfo> processInfoList = new ArrayList<>();

        List<CrossServerInfo> serverInfoList = new CrossServerInfoDaoImpl().getAllChannelCrossServerInfo(channelId);
        serverInfoList.removeIf(next -> (next.getCrossServerType() != CrossServerType.RANK_CROSS_2));

        for (CrossServerInfo crossServerInfo : serverInfoList) {
            if(Config.isDebug() && crossServerInfo.getCrossServerId() != 99900177 && crossServerInfo.getCrossServerId() != 99905020 && crossServerInfo.getCrossServerId() != 99905001){
                continue;
            }

            for (ProcessInfo processInfo : crossServerInfo.getProcessInfoList()) {
                if(processInfo.getServerName().equals("cross_server")) {
                    processInfoList.add(processInfo);
                }
            }
        }

        ExecutorService webExecutor = WebServer.getWebExecutor();
        List<Long> errorCrossServerIdList = new ArrayList<>();
        try {
            //遍历异步通知活动跨服
            CountDownLatch countDownLatch = new CountDownLatch(processInfoList.size());
            JSONObject param = new JSONObject();
            param.put("content", "CrossCricketCourtMgr");
            for (ProcessInfo processInfo : processInfoList) {
                webExecutor.execute(() -> {
                    try {
                        String url = "http://" + processInfo.getAddress() + ":" + processInfo.getAdminPort() + "/crossws?wsdl";
                        QName qName = new QName("http://webservice.server.road.yanqu.com/", "GrossWebServiceService");
                        Service service = Service.create(new URL(url), qName);
                        ICrossWebService crossWebService = service.getPort(ICrossWebService.class);
                        String resp = crossWebService.executeAdminOperate("AgentReload|reloadMgr", param.toJSONString(), "Yanqu123");
                        JSONObject result = JSONObject.parseObject(resp);
                        int status = result.getInteger("status");
                        if (status != 1) {
                            errorCrossServerIdList.add((long) processInfo.getServerId());
                        }
                    } catch (Exception e) {
                        errorCrossServerIdList.add((long) processInfo.getServerId());
                    } finally {
                        countDownLatch.countDown();
                    }
                });
            }
            //等待
            if (!countDownLatch.await(30, TimeUnit.SECONDS)) {
                ServerListMgr.getLogger().error("刷新超时");
            }
        } catch (Exception e) {
            ServerListMgr.getLogger().error("", e);
        }

        //刷新区服
        List<ServerInfo> channelServerList = ServerListMgr.getChannelServerList(channelId);
        if(channelServerList.size() > 0){
            List<Future> futureList = new ArrayList<>();
            Map<String, String> paramMap = new HashMap<>();
            JSONObject param = new JSONObject();
            param.put("name", "CricketMgr");
            JSONObject param1 = new JSONObject();
            param1.put("param", param);
            paramMap.put("param", param1.toJSONString());
            for (ServerInfo serverInfo : channelServerList) {
                Future future = webExecutor.submit(new Callable<Boolean>() {
                    @Override
                    public Boolean call() throws Exception {
                        String result = "";
                        try {
                            result = HttpHelper.doPost(serverInfo.getWebServerUrl() + "/reloadMgr", paramMap, "UTF-8");
                            JSONObject jsonObject = JSONObject.parseObject(result);
                            if (jsonObject.getIntValue("status") != 0) {

                            }else {
                                ServerListMgr.getLogger().error("error, 区服 {} 刷新失败", serverInfo.getServerId());
                                errorCrossServerIdList.add(serverInfo.getServerId());
                            }
                        } catch (Exception ex) {
                            ServerListMgr.getLogger().error("error, {} {}", result == null ? "" : result, ex.toString());
                            errorCrossServerIdList.add(serverInfo.getServerId());
                        }
                        return true;
                    }
                });
                futureList.add(future);
            }
            if(!futureList.isEmpty()) {
                for (Future future : futureList) {
                    try {
                        boolean ret = (boolean) future.get(10, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } catch (TimeoutException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        AdminResult result = AdminResult.defaultInstance();
        result.getData().put("serverIds", StringUtils.listToString(errorCrossServerIdList, ","));
        return result.toJsonString();
    }


    /**
     *  63.3 查询
     */
    @ResponseBody
    @RequestMapping(value = "searchCricketConfig", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
    public String searchCricketConfig(HttpServletRequest request, @RequestBody JSONObject jsonObject) {

        int channelId = jsonObject.getIntValue("channelId");

        int pageNum = jsonObject.getIntValue("pageNum");
        int pageSize = jsonObject.getIntValue("pageSize");

        int startIndex = (pageNum - 1) * pageSize;
        startIndex = Math.max(0, startIndex);

        List<Integer> systemConfigIdList = new AdminCommonDaoImpl().getBatchCricketConfigId(channelId);

        List<Integer> searchList = new ArrayList<>();
        for (int i = startIndex; i < startIndex + pageSize && i < systemConfigIdList.size(); i++) {
            searchList.add(systemConfigIdList.get(i));
        }

        List<CricketCourtConfig> systemConfigList = new AdminCommonDaoImpl().getChannelCricketConfig(searchList, channelId);

        AdminResult result = AdminResult.defaultInstance();

        result.getData().put("total", systemConfigIdList.size());

        List<Map<String, Object>> list = new ArrayList<>();
        for (CricketCourtConfig systemConfig : systemConfigList) {
            Map<String, Object> map = new HashMap<>();
            map.put("channelId", channelId);
            map.put("courtType", systemConfig.getCourtType());
            map.put("courtName", systemConfig.getCourtName());
            map.put("serverRange", systemConfig.getFightRangeServer());
            map.put("openServerDays", systemConfig.getFightRangeDay());
            map.put("membersNum", systemConfig.getNum());
            map.put("groupsLimit", systemConfig.getGroupLimit());
            map.put("roundRisePermillage", systemConfig.getUpNum());
            map.put("roundReservePermillage", systemConfig.getKeepNum());
            map.put("groupRemainderUpperLimit", systemConfig.getModLimit());
            map.put("endReward", systemConfig.getReward());
            map.put("rankReward", systemConfig.getRankReward());
            map.put("courtSwitch", systemConfig.getCourtState());
            list.add(map);
        }
        result.getData().put("row", list);

        return result.toJsonString();

    }

}
